﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Linq.Expressions;
using XYAC.Framework.MonitorTireMaterialOnline.Entities;
using XYAC.Framework.MonitorTireMaterialOnline.Extensions;

namespace XYAC.Framework.MonitorTireMaterialOnline.IServices
{
    /// <summary>
    /// 服务基础类
    /// </summary>
    /// <typeparam name="TType"></typeparam>
    public interface IServiceBase<TType, TContext>
        where TType : IEquatable<TType>, new()
        where TContext : DbContext
    {
        /// <summary>
        /// 应用程序配置
        /// </summary>
        IOptionsMonitor<AppConfig> AppConfig { get; }

        /// <summary>
        /// 日志记录器
        /// </summary>
        ILogger Logger { get; }

        /// <summary>
        /// 新增实体数据(Common)
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="obj">主键ID</param>
        /// <returns></returns>
        bool Add<T>(T obj) where T : EntityBase<TType>, new();

        /// <summary>
        /// 更新实体数据(Common)
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="obj">主键ID</param>
        /// <returns></returns>
        bool Update<T>(T obj) where T : EntityBase<TType>, new();
        /// <summary>
        /// 删除数据(Common)
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        bool Delete<T>(TType id) where T : EntityBase<TType>, new();

        /// <summary>
        /// 删除数据(Common)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ints"></param>
        bool Delete<T>(TType[] ints) where T : EntityBase<TType>, new();
        /// <summary>
        /// 删除数据(Common)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="preDeleteData"></param>
        bool Delete<T>(IEnumerable<T> preDeleteData) where T : EntityBase<TType>, new();
        /// <summary>
        /// 获取所有EntityBase数据(Common)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filterCondition">条件</param>
        /// <returns></returns>
        IEnumerable<T> GetAll<T>(params Expression<Func<T, bool>>[] filterCondition) where T : EntityBase<TType>, new();

        /// <summary>
        /// 获取所有EntityBase数据(Common)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        IEnumerable<T> GetAll<T>() where T : EntityBase<TType>, new();
        /// <summary>
        /// 获取主键数据(Common)
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="id">主键ID</param>
        /// <returns></returns>
        T GetById<T>(TType id) where T : EntityBase<TType>, new();

        /// <summary>
        /// 分页获取数据(Common)
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="pageIndex">页索引</param>
        /// <param name="rowCount">页行数</param>
        /// <param name="filterExpressions">过滤条件</param>
        /// <param name="orderByExpressions">正向排序条件</param>
        /// <param name="orderByDescExpressions">逆向排序条件</param>
        /// <returns></returns>
        IEnumerable<T> GetPage<T>(
              int pageIndex,
              int pageSize,
              List<Expression<Func<T, bool>>> filterConditions = null,
              List<(Expression<Func<T, object>> KeySelector, bool Descending)> orderConditions = null)
              where T : class, new();

        /// <summary>
        /// 获取非重复项(Common)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="expression"></param>
        /// <returns></returns>
        IEnumerable<T2> GetDistinct<T, T2>(Func<T, T2> expression) where T : EntityBase<TType>, new();

        /// <summary>
        /// 获取总数(Common)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="filterCondition"></param>
        /// <returns></returns>
        int GetCount<T>(Expression<Func<T, bool>> filterCondition = null) where T : EntityBase<TType>, new();
    }
}
